package model

import (
	"devOpsApi/common/sonar"
	"devOpsApi/config/ymlgo"
	"devOpsApi/model"
	"errors"
	"strconv"
	"strings"
)

type Sonar struct {
	Cli *sonargo.Client
}

type Condition struct {
	NewList []ConditionNewList
	AllList []ConditionAllList
}

type ConditionNewList struct {
	Metric   string
	Op       string
	ChMetric string
	ChOp     string
	Symbol   string
}

type ConditionAllList struct {
	Metric   string
	Op       string
	ChMetric string
	ChOp     string
	Symbol   string
}

const Separator = "____"

func NewSonar() (*Sonar, error) {
	config := ymlgo.NewConfigSysBase()
	client, err := sonargo.NewClient(config.SonarHost+"/api", config.SonarToken, "")
	if err != nil {
		return nil, err
	}
	return &Sonar{
		Cli: client,
	}, nil
}

func (m *Sonar) UserAll(uid uint) ([]*sonargo.QualityGateV2, error) {
	list, _, err := m.Cli.Qualitygates.List(&sonargo.QualitygatesListOption{})
	if err != nil {
		return nil, err
	}
	NewList := m.adminCheckList(uid, list)
	return NewList, nil
}

func (m *Sonar) Create(uid uint, name string) (qualityGate *sonargo.QualityGate, err error) {
	name = name + Separator + strconv.Itoa(int(uid))
	qualityGate, _, err = m.Cli.Qualitygates.Create(&sonargo.QualitygatesCreateOption{Name: name})
	return
}

func (m *Sonar) UpdateVisibility(uid uint, name, visibility string) (err error) {
	name = name + Separator + strconv.Itoa(int(uid))
	_, err = m.Cli.Projects.UpdateVisibility(&sonargo.ProjectsUpdateVisibilityOption{Project: name, Visibility: visibility})
	return
}

func (m *Sonar) Update(uid uint, id, name string) (qualityGate *sonargo.QualityGate, err error) {
	_qualityGate, _, err := m.Cli.Qualitygates.Show(&sonargo.QualitygatesShowOption{Id: id})
	if err != nil {
		return nil, err
	}
	names := strings.Split(_qualityGate.Name, Separator)
	if len(names) == 1 {
		return nil, errors.New("该质量阀不属于任何用户！")
	}
	names_uid, _ := strconv.Atoi(names[1])
	if uint(names_uid) != uid {
		return nil, errors.New("非法操作，该质量阀不属于该用户！")
	}
	//name = name + Separator + strconv.Itoa(int(uid))
	qualityGate, _, err = m.Cli.Qualitygates.Rename(&sonargo.QualitygatesRenameOption{Id: id, Name: name})
	return
}

func (m *Sonar) Detail(uid uint, name string) (qualityGate *sonargo.QualityGateV2, err error) {
	if err := m.adminCheck(uid, name); err != nil {
		return nil, err
	}
	qualityGate, _, err = m.Cli.Qualitygates.Show(&sonargo.QualitygatesShowOption{Name: name})
	if err != nil {
		return nil, err
	}
	names := strings.Split(qualityGate.Name, Separator)
	if len(names) == 2 {
		qualityGate.ShowName = m.RealName(qualityGate.Name)
	}
	return
}

func (m *Sonar) Del(uid uint, name string) (err error) {
	if err := m.adminCheck(uid, name); err != nil {
		return err
	}
	_, err = m.Cli.Qualitygates.Destroy(&sonargo.QualitygatesDestroyOption{Name: name})
	return
}

func (m *Sonar) CreateCondition(errinfo, gateId, metric, op string) (qualityGatesCondition *sonargo.QualityGatesCondition, err error) {
	qualityGatesCondition, _, err = m.Cli.Qualitygates.CreateCondition(&sonargo.QualitygatesCreateConditionOption{Error: errinfo, GateId: gateId, Metric: metric, Op: op})
	return
}

func (m *Sonar) UpdateCondition(errinfo, metric, op string, conditionID string) (qualityGatesCondition *sonargo.QualityGatesCondition, err error) {
	qualityGatesCondition, _, err = m.Cli.Qualitygates.UpdateCondition(&sonargo.QualitygatesUpdateConditionOption{Error: errinfo, Id: conditionID, Metric: metric, Op: op})
	return
}

func (m *Sonar) DeleteCondition(conditionID string) (err error) {
	_, err = m.Cli.Qualitygates.DeleteCondition(&sonargo.QualitygatesDeleteConditionOption{ConditionID: conditionID})
	return
}

/*
metric:
INT 整形
MILLISEC 毫秒
RATING ABCD
WORK_DUR 工作时间
FLOAT 浮点型
PERCENT 百分比
LEVEL

op:
LT = is lower than
GT = is greater than
*/
func (m *Sonar) ConditionList() Condition {
	ConditionNewList := []ConditionNewList{
		{Metric: "", ChMetric: "覆盖率", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_branch_coverage", ChMetric: "分支覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "new_conditions_to_cover", ChMetric: "可覆盖分支", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_coverage", ChMetric: "覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "new_line_coverage", ChMetric: "代码覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "new_lines_to_cover", ChMetric: "可覆盖行", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_uncovered_conditions", ChMetric: "未覆盖分支", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_uncovered_lines", ChMetric: "未覆盖的代码", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "重复", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_duplicated_blocks", ChMetric: "重复块", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_duplicated_lines_density", ChMetric: "重复行(%)", Op: "GT", ChOp: "大于", Symbol: "PERCENT"},
		{Metric: "new_duplicated_lines", ChMetric: "重复行", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "问题", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_blocker_violations", ChMetric: "阻断违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_critical_violations", ChMetric: "严重违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_info_violations", ChMetric: "提示违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_violations", ChMetric: "违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_major_violations", ChMetric: "主要违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_minor_violations", ChMetric: "次要违规", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "可维护性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_technical_debt", ChMetric: "新代码的技术债务", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},
		{Metric: "new_maintainability_rating", ChMetric: "SQALE评级", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "new_code_smells", ChMetric: "异味", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_sqale_debt_ratio", ChMetric: "技术债务比率", Op: "GT", ChOp: "大于", Symbol: "PERCENT"},

		{Metric: "", ChMetric: "可靠性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_bugs", ChMetric: "Bugs", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_reliability_rating", ChMetric: "可靠性比率", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "new_reliability_remediation_effort", ChMetric: "可靠性修复工作", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},

		{Metric: "", ChMetric: "安全性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_vulnerabilities", ChMetric: "漏洞", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "new_security_rating", ChMetric: "安全比率", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "new_security_remediation_effort", ChMetric: "安全修复工作", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},

		{Metric: "", ChMetric: "安全复审", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_security_hotspots_reviewed", ChMetric: "安全热点复审", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "new_security_review_rating", ChMetric: "安全审核等级", Op: "GT", ChOp: "劣于", Symbol: "RATING"},

		{Metric: "", ChMetric: "大小", Op: "", ChOp: "", Symbol: ""},
		{Metric: "new_lines", ChMetric: "行数", Op: "GT", ChOp: "大于", Symbol: "INT"},
	}

	ConditionAllList := []ConditionAllList{
		{Metric: "", ChMetric: "复杂度", Op: "", ChOp: "", Symbol: ""},
		{Metric: "cognitive_complexity", ChMetric: "认知复杂度", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "complexity", ChMetric: "圈复杂度", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "覆盖率", Op: "", ChOp: "", Symbol: ""},
		{Metric: "branch_coverage", ChMetric: "分支覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "conditions_to_cover", ChMetric: "可覆盖分支", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "coverage", ChMetric: "覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "line_coverage", ChMetric: "代码覆盖率", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "lines_to_cover", ChMetric: "可覆盖行", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "skipped_tests", ChMetric: "单元测试忽略数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "uncovered_conditions", ChMetric: "未覆盖分支", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "uncovered_lines", ChMetric: "未覆盖的代码", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "test_execution_time", ChMetric: "单元测试持续时间", Op: "GT", ChOp: "大于", Symbol: "MILLISEC"},
		{Metric: "test_errors", ChMetric: "单元测试错误数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "test_failures", ChMetric: "单元测试失败数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "test_success_density", ChMetric: "单元测试成功 (%)", Op: "GT", ChOp: "大于", Symbol: "PERCENT"},
		{Metric: "tests", ChMetric: "单元测试数", Op: "LT", ChOp: "小于", Symbol: "INT"},

		{Metric: "", ChMetric: "重复", Op: "", ChOp: "", Symbol: ""},
		{Metric: "duplicated_blocks", ChMetric: "重复块", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "duplicated_files", ChMetric: "重复文件", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "duplicated_lines_density", ChMetric: "重复行(%)", Op: "GT", ChOp: "大于", Symbol: "PERCENT"},
		{Metric: "duplicated_lines", ChMetric: "重复行", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "问题", Op: "", ChOp: "", Symbol: ""},
		{Metric: "blocker_violations", ChMetric: "阻断违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "confirmed_issues", ChMetric: "确认问题", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "critical_violations", ChMetric: "严重违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "false_positive_issues", ChMetric: "误判问题", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "info_violations", ChMetric: "提示违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "violations", ChMetric: "违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "major_violations", ChMetric: "主要违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "minor_violations", ChMetric: "次要违规", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "open_issues", ChMetric: "开启问题", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "reopened_issues", ChMetric: "重开问题", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "wont_fix_issues", ChMetric: "不修复的问题", Op: "GT", ChOp: "大于", Symbol: "INT"},

		{Metric: "", ChMetric: "可维护性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "code_smells", ChMetric: "异味", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "effort_to_reach_maintainability_rating_a", ChMetric: "达到可维护性A级所需的工作", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},
		{Metric: "sqale_index", ChMetric: "技术债务", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},
		{Metric: "maintainability_rating", ChMetric: "SQALE评级", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "sqale_debt_ratio", ChMetric: "技术债务比率", Op: "GT", ChOp: "大于", Symbol: "PERCENT"},

		{Metric: "", ChMetric: "可靠性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "bugs", ChMetric: "Bugs", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "reliability_rating", ChMetric: "可靠性比率", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "reliability_remediation_effort", ChMetric: "可靠性修复工作", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},

		{Metric: "", ChMetric: "安全性", Op: "", ChOp: "", Symbol: ""},
		{Metric: "vulnerabilities", ChMetric: "漏洞", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "security_rating", ChMetric: "安全比率", Op: "GT", ChOp: "劣于", Symbol: "RATING"},
		{Metric: "security_remediation_effort", ChMetric: "安全修复工作", Op: "GT", ChOp: "大于", Symbol: "WORK_DUR"},

		{Metric: "", ChMetric: "安全复审", Op: "", ChOp: "", Symbol: ""},
		{Metric: "security_hotspots_reviewed", ChMetric: "安全热点复审", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "security_review_rating", ChMetric: "安全审核等级", Op: "GT", ChOp: "劣于", Symbol: "RATING"},

		{Metric: "", ChMetric: "大小", Op: "", ChOp: "", Symbol: ""},
		{Metric: "classes", ChMetric: "类", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "comment_lines", ChMetric: "注释行", Op: "LT", ChOp: "小于", Symbol: "INT"},
		{Metric: "comment_lines_density", ChMetric: "注释 (%)", Op: "LT", ChOp: "小于", Symbol: "PERCENT"},
		{Metric: "directories", ChMetric: "目录", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "files", ChMetric: "文件", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "functions", ChMetric: "方法", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "generated_lines", ChMetric: "生成的行数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "generated_ncloc", ChMetric: "生成的代码行数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "lines", ChMetric: "行数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "ncloc", ChMetric: "代码行数", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "projects", ChMetric: "项目", Op: "GT", ChOp: "大于", Symbol: "INT"},
		{Metric: "statements", ChMetric: "语句", Op: "GT", ChOp: "大于", Symbol: "INT"},
	}

	conditionList := Condition{
		NewList: ConditionNewList,
		AllList: ConditionAllList,
	}
	return conditionList
}

func (m *Sonar) adminCheck(uid uint, name string) error {
	names := strings.Split(name, Separator)
	if len(names) == 2 {
		roleUser, _ := model.NewUserRoleUser().GetUserRole(int(uid))
		if roleUser.RoleId != 1 { //非超级管理员
			names_uid, _ := strconv.Atoi(names[1])
			if uint(names_uid) != uid {
				return errors.New("非法操作")
			}
		}
	}
	return nil
}

func (m *Sonar) adminCheckList(uid uint, list *sonargo.QualitygatesListObject) []*sonargo.QualityGateV2 {
	roleUser, _ := model.NewUserRoleUser().GetUserRole(int(uid))
	var NewList []*sonargo.QualityGateV2
	if roleUser.RoleId != 1 {
		for _, v := range list.Qualitygates {
			if v.IsDefault == true { //公共默认质量阀
				NewList = append(NewList, v)
				continue
			}

			//用户自定义阀值
			names := strings.Split(v.Name, Separator)
			if len(names) == 2 {
				names_uid, _ := strconv.Atoi(names[1])
				if uint(names_uid) == uid {
					NewList = append(NewList, v)
				}
			}
		}
	} else {
		NewList = list.Qualitygates
	}
	for _, v := range NewList {
		names := strings.Split(v.Name, Separator)
		if len(names) == 2 {
			v.ShowName = m.RealName(v.Name)
		}
	}
	return NewList
}

func (m *Sonar) RealName(name string) string {
	if name == "" {
		return ""
	}
	names := strings.Split(name, Separator)
	if len(names) == 2 {
		return names[0]
	}
	return name
}

func (m *Sonar) ProjectDetail(name string) (searchObject *sonargo.ProjectSearchObject, err error) {
	searchObject, _, err = m.Cli.Projects.Search(&sonargo.ProjectsSearchOption{Projects: name})
	return
}

func (m *Sonar) ProjectDel(project string) (err error) {
	_, err = m.Cli.Projects.Delete(&sonargo.ProjectsDeleteOption{Project: project})
	return
}
